package com.travelsky.app.security.support;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.ConfigAttributeDefinition;
import org.springframework.security.ConfigAttributeEditor;
import org.springframework.security.intercept.web.FilterInvocation;
import org.springframework.security.intercept.web.FilterInvocationDefinitionSource;
import org.springframework.security.util.AntUrlPathMatcher;
import org.springframework.security.util.RegexUrlPathMatcher;
import org.springframework.security.util.UrlMatcher;
import com.travelsky.app.security.SecurityManager;
/**
 * 
 * 项目名称：travelsky   
 * 类名称：SecureResourceFilterInvocationDefinitionSource   
 * 类描述：对资源进行认证的过滤器
 * 创建人：gchzhou gczhou@travelsky.com 
 * 创建时间：2011-5-17 上午10:05:22   
 * 修改人： gchzhou gczhou@travelsky.com
 * 修改时间：2011-5-17 上午10:05:22   
 * 修改备注：   
 * @version 1.0
 */
public class SecureResourceFilterInvocationDefinitionSource implements FilterInvocationDefinitionSource, InitializingBean {
    
    private UrlMatcher urlMatcher;  
    
    private boolean useAntPath = true;  
      
    private boolean lowercaseComparisons = true; 
    
    @Autowired
    private SecurityManager securityManager;
    /**
     * (非 Javadoc)
     * 
     * 核心方法
     * @param filter
     * @return
     * @throws IllegalArgumentException
     * @see org.springframework.security.intercept.ObjectDefinitionSource#getAttributes(java.lang.Object)
     */
    @Override
    public ConfigAttributeDefinition getAttributes(Object filter) throws IllegalArgumentException {
        //获得请求的URL
        FilterInvocation filterInvocation = (FilterInvocation) filter;
        String requestURI = filterInvocation.getRequestUrl();
        //获取拥有的所有的资源
        Map<String, String> urlAuthorities = this.getUrlAuthorities();
        String grantedAuthorities = null;
        for(Iterator<Map.Entry<String, String>> iter = urlAuthorities.entrySet().iterator(); iter.hasNext();) {
            Map.Entry<String, String> entry = iter.next();
            String url = entry.getKey();
            //请求的URL和你拥有的url比对
            if(urlMatcher.pathMatchesUrl(url, requestURI)){//ok
                grantedAuthorities = entry.getValue();  
                break;  
            }
        }
        //如果资源认证通过
        if(grantedAuthorities != null) {
            //放行，通过
            ConfigAttributeEditor configAttrEditor = new ConfigAttributeEditor();
            configAttrEditor.setAsText(grantedAuthorities);
            return (ConfigAttributeDefinition) configAttrEditor.getValue();
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    public Collection getConfigAttributeDefinitions() {
        return null;
    }

    @SuppressWarnings("unchecked")
    public boolean supports(Class arg0) {
        return true;
    }

    @SuppressWarnings("unchecked")
    public void afterPropertiesSet() throws Exception {
        this.urlMatcher = new RegexUrlPathMatcher();  
        
        if (useAntPath) {  // change the implementation if required  
            this.urlMatcher = new AntUrlPathMatcher();  
        }  
          
        // Only change from the defaults if the attribute has been set  
        if ("true".equals(lowercaseComparisons)) {  
            if (!this.useAntPath) {  
                ((RegexUrlPathMatcher) this.urlMatcher).setRequiresLowerCaseUrl(true);  
            }  
        } else if ("false".equals(lowercaseComparisons)) {  
            if (this.useAntPath) {  
                ((AntUrlPathMatcher) this.urlMatcher).setRequiresLowerCaseUrl(false);  
            }  
        }  
    }
    
    private Map<String, String> getUrlAuthorities() {
        Map<String, String> urlAuthorities = securityManager.loadUrlAuthorities();
        return urlAuthorities;
    }

    public UrlMatcher getUrlMatcher() {
        return urlMatcher;
    }

    public void setUrlMatcher(UrlMatcher urlMatcher) {
        this.urlMatcher = urlMatcher;
    }

    public boolean isUseAntPath() {
        return useAntPath;
    }

    public void setUseAntPath(boolean useAntPath) {
        this.useAntPath = useAntPath;
    }

    public boolean isLowercaseComparisons() {
        return lowercaseComparisons;
    }

    public void setLowercaseComparisons(boolean lowercaseComparisons) {
        this.lowercaseComparisons = lowercaseComparisons;
    }
    
}
